Продолжаем развитие нашего проекта дальше.
Это вписывается после последнего #define. Вот сюда:

Мы записываем объявление класса в самое начало, чтобы его было видно во всем файле.
class CMyButton: public CButton
{
public:
afx_msg void OnLButtonDblClk(UINT, CPoint);
afx_msg void OnRButtonDblClk(UINT, CPoint);
private:
DECLARE_MESSAGE_MAP(); // таблица откликов кнопки
};
void CMyButton::OnLButtonDblClk(UINT, CPoint)
{
MoveWindow(CRect(120,100,220,150),TRUE);
}
void CMyButton::OnRButtonDblClk(UINT, CPoint)
{
MoveWindow(CRect(120,10,220,50),TRUE);
}
BEGIN_MESSAGE_MAP(CMyButton, CButton) // таблица откликов на сообщения
ON_WM_LBUTTONDBLCLK()
ON_WM_RBUTTONDBLCLK()
END_MESSAGE_MAP()
После добавления описания класса в окне ClassView мы сможем увидеть, что добавился новый класс:

И изменяем класс кнопки в рамке окна:
class CMainWnd : public CFrameWnd
{
public:
CMainWnd();
afx_msg void OnLButtonDblClk(UINT, CPoint);
afx_msg void OnRButtonDblClk(UINT, CPoint);
afx_msg void OnKeyDown(UINT, UINT, UINT);
private:
CStatic* MyStatic; // Элемент управления для вывода текста
CMyButton* MyButton;// Элемент управления кнопка
CEdit* MyEdit; // Элемент редактирования
DECLARE_MESSAGE_MAP(); // таблица откликов
};
Меняем часть конструктора:
CMainWnd::CMainWnd()
{
Create(NULL,"Step4",WS_OVERLAPPEDWINDOW,rectDefault,
NULL,NULL); // Создать окно программы
// оператор new по умолчанию в случае ошибки вернет NULL
// проверка указателя на NULL дает возможность избавиться от дальнейших ошибок
MyStatic = new CStatic();
if (MyStatic!=NULL) MyStatic->Create("MyStatic",WS_CHILD|WS_VISIBLE|SS_CENTER,
CRect(10,10,100,50),this); // создали
MyButton = new CMyButton(); // Меняем класс, на основе которого создается объект
if (MyButton!=NULL) MyButton->Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER,
CRect(120,10,220,50),this,IDC_MYBUTTON);
MyEdit = new CEdit();
if (MyEdit!=NULL) MyEdit->Create(WS_CHILD|WS_VISIBLE|WS_BORDER,
CRect(240,10,340,50),this,IDC_MYEDIT);
}
Главная идея этого шага понять, каким методом можно изменить поведение элемента управления, и не только его. С помощью таблиц откликов можно поменять поведение практически любого объекта MFC.
Первым делом, мы создадим свой класс кнопки. Чтобы не делать все сначала, мы возьмем готовый CButton и породим от него свой CMyButton. Так же, как и вы унаследовали от родителей глаза, уши и плохие привычки, так и CMyButton точная копия CButton. Правило такое - сын точная копия папы. Public означает, что папа родной, не отчим. Получение точной копии выглядит так:
class Сын : public Папа
Пора перевоспитать наш CButton под новые требования. Добавили таблицу откликов и описали функции реакции - это знакомо по предыдущему шагу. Правило: детей надо воспитывать, иначе толку никакого.
Внутри функции отклика на кнопку есть функция MoveWindow - эта функция перемещает окно в заданное место. В описании класса CButton этого свойства нет. Но класс CButton тоже сын от CWnd, а в нем это свойство есть. Очередное правило: нет метода у сына - посмотри у папы.
И последнее. В классе главного окна изменить ссылку с CButton на CMyButton. Здесь логично. Выйти замуж за папу или сына разница большая. Естественно и процесс создания и вызова методов нужно изменять.
Все по старому: компиляция, сбор, запуск. По двойному щелчку левой кнопкой объект кнопка переместится вниз, а по щелчку правой вверх. Вот это да!

class CMyButton: public CButton
class CMyButton: public CButton
{
public:
afx_msg void OnLButtonDblClk(UINT, CPoint);
......
CMyButton* MyButton;
MyButton = new CMyButton();
if (MyButton!=NULL) MyButton-> Create("MyButton",WS_CHILD|WS_VISIBLE|SS_CENTER,
CRect(120,10,220,50),this,IDC_MYBUTTON);